﻿using AForge.Video;
using AForge.Video.DirectShow;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using System.Threading;

namespace attendanceDemo
{
    public partial class Form1 : Form
    {
        private readonly Dictionary<string, byte[]> faceCache = new Dictionary<string, byte[]>();
        private const string FaceLibraryPath = "人脸库";
        private Object lockPicture = new Object();
        private Faces faces = new Faces();
        private IVideoSource videoSource;
        private Boolean showImage = false;
        SynchronizationContext m_SyncContext = null;
        private byte[] currentBitmapFaceBytes;

        public Form1()
        {
            InitializeComponent();
            m_SyncContext = SynchronizationContext.Current;
            LoadFace(FaceLibraryPath);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            videoSource = new FileVideoSource("司马懿重读出师表.avi");
            videoSource.NewFrame += VideoSourceFPS;
            videoSource.PlayingFinished += VideoSourceRePlayer;
            videoSource.Start();
        }

        private void VideoSourceRePlayer(object sender, AForge.Video.ReasonToFinishPlaying reason)
        {
            Console.WriteLine("播放完成");
            videoSource.Start();
        }

        private void VideoSourceFPS(object sender, AForge.Video.NewFrameEventArgs eventArgs)
        {
            Bitmap bitmap = eventArgs.Frame;
            if (bitmap == null) {
                return;
            }
            
            using (bitmap)
            {
                if (showImage)
                {
                    bitmap.Save("showImage.jpg");
                    Bitmap showBitmap = new Bitmap("showImage.jpg");
                    pictureBox2.Image = faces.ZoomImage(showBitmap, pictureBox2.Width, pictureBox2.Height);
                    showImage = false;
                }

                Bitmap zoomImg = faces.ZoomImage(bitmap, pictureBox1.Width, pictureBox1.Height);
                if (faces.FaceTracking(zoomImg) && currentBitmapFaceBytes == null)
                {
                    currentBitmapFaceBytes = faces.BitmapByte(zoomImg);
                    
                }
                pictureBox1.Image = zoomImg;
            }
        }

        private void SetTextSafePost(object name)
        {
            textBox1.AppendText(DateTime.Now.ToLongTimeString() + "  " +  name.ToString() + "\r\n");

        }

        private void button1_Click(object sender, EventArgs e)
        {
            showImage = true;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            string value = InputBox.Input("提示", "请输入当前人脸姓名", DateTime.Now.ToLongTimeString());
            Bitmap showBitmap = new Bitmap("showImage.jpg");
            showBitmap = faces.ZoomImage(showBitmap, 640, 480);
            if (faces.FaceFeatureData(showBitmap) == null) {
                MessageBox.Show("当前图片中不存在人脸或存在多张人脸");
                return;
            }
            showBitmap.Save(Path.Combine(FaceLibraryPath, value + ".jpg"));
            AddFileToListView(showBitmap, value);
            MessageBox.Show("保存成功");
        }

        private void AddFileToListView(Bitmap bitmap,string name) {

            byte[] bytes = faces.FaceFeatureData(bitmap);
            if (bytes != null)
            {
                imageList1.Images.Add(name, bitmap);
                ListViewItem lvi = new ListViewItem(new string[] { name });
                lvi.ImageKey = name;
                listView1.Items.Add(lvi);
                faces.AddFaceToCache(name, bytes);
            }
        }

        public void LoadFace(string path) {
            if (!Directory.Exists(FaceLibraryPath))
            {
                Directory.CreateDirectory(FaceLibraryPath);
            }
            IEnumerable<string> files = Directory.EnumerateFiles(path);
            foreach(string file in files)
            {
                if (file.EndsWith(".jpg")) {
                    FileInfo fi = new FileInfo(file);
                    AddFileToListView(new Bitmap(file), fi.Name.Split('.')[0]);
                }
            }
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            videoSource.Stop();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (currentBitmapFaceBytes != null)
            {
                m_SyncContext.Post(SetTextSafePost,"正在识别");
                MemoryStream ms =  new MemoryStream(currentBitmapFaceBytes);
                Image bitmap = Bitmap.FromStream(ms);

                Bitmap b = new Bitmap(640,480);
                Graphics g = Graphics.FromImage(b);
                g.DrawImage(bitmap, new Rectangle(0, 0, 640, 480));
                string name = faces.FaceRecognize(b);
                if (name.Length > 0) {
                    m_SyncContext.Post(SetTextSafePost, "识别成功："+name);
                }
                ms.Dispose();
                b.Dispose();
                currentBitmapFaceBytes = null;
            }

            if (!videoSource.IsRunning) {
                videoSource.Start();
            }
        }
    }
}
